<?php
#自动化热更新类
class libVar
{
    private $_value = NULL;

    /* 参数获取 */
    private function _removeEmoji($text)
    {
        // 匹配4字节的unicode
        $regexEmoticons = '/[\x{10000}-\x{10FFFF}]/u';
        $text = preg_replace($regexEmoticons, '', $text);
        return $text;
    }

    //过滤特殊字符
    private function _filterSpecialChars($str, $isEmoji = TRUE)
    {

        //删除零宽度空格符(zero-width-space)
        $str = str_replace("\xe2\x80\x8b", '', $str);
        $str = str_replace("\xe2\x80\x8c", '', $str);
        $str = str_replace("\xe2\x80\x8d", '', $str);
        $str = str_replace("\xe2\x80\xac", '', $str);
        $str = str_replace("\xe2\x80\xad", '', $str);

        //移除emojo表情
        if($isEmoji){
            $str = $this->_removeEmoji($str);
        }

        return $str;
    }

    /**
     * @param bool   $trim
     * @param string $default
     * @param null   $length
     * @param null   $start
     * @return mixed|null|string
     */
    private function _toString($default = '', $length = NULL, $start = NULL, $isEmoji = TRUE)
    {
        if(is_null($this->_value)){
            return $default;
        }
        $value = $this->_filterSpecialChars($this->_value, $isEmoji);
        if($length === NULL && $start === NULL){
            return $value;
        } elseif($start === NULL){
            return substr($value, 0, $length);
        } elseif($length === NULL){
            return substr($value, $start);
        } else{
            return substr($value, $start, $length);
        }
    }

    /**
     * @param string $name
     * @param bool   $trim
     * @param null   $default
     * @param string $filter
     * @return string
     */
    public function post($name = '', $trim = TRUE)
    {
        $this->_value = $_POST[$name];
        $string = $this->_toString("");
        $string = trim(htmlspecialchars($string, ENT_QUOTES));
        return $string;
    }

    public function response($msg, $result, $code, $isJsonUnescapedUnicode = 1)
    {
        $data = [
            'code'    => $code,
            'result'  => $result,
            'message' => $msg,
        ];
        if($isJsonUnescapedUnicode){
            $original = json_encode($data, JSON_UNESCAPED_UNICODE);
        } else{
            $original = json_encode($data);
        }
        echo $original;
        exit();
    }
}

class libUploader
{
    private $_option = [
        "savePath"  => "uploadfile",//文件的保存路径:./uploadfile
        'prefix'    => FALSE, //文件名前缀
        "limitSize" => 4096000, //4M，定义文件大小，单位k
        "limitHz"   => ["wgtu"],
        "fileSize"  => 0,//文件大小
        "fileHz"    => 0//文件后缀
    ];

    //内部封装的参数$_fileName
    private $_fileSaveName; //文件保存名称
    private $_fileName; //文件名称
    private $_filePath;  //上传的文件路径上传文件名字
    private $_newFileName; //新文件名称
    private $_fileSize; //源文件的大小
    private $_fileHz; //文件名后缀
    private $_code = 0;
    private $_data = [];
    private $_msg = [
        0 => "上传成功"
    ];
    private $_fileInfoStatus = TRUE;

    public function __construct($option)
    {
        $this->setOption($option);
        //初始化文件路径
        $this->_fileHz = $this->_option['fileHz'];
        $this->_fileInfoStatus = $this->_setFileInfo();
    }

    //设置初始化参数
    private function setOption($option = [])
    {
        foreach($option as $key => $v){
            $this->_option[$key] = $v;
        }
        foreach($this->_option['limitHz'] as $key => $v){
            $this->_option['limitHz'][$key] = strtolower($v);
        }

    }


    /**
     * 设置文件信息
     * @return bool
     */
    private function _setFileInfo()
    {
        //走表单上传
        $fileInfo = $_FILES;
        if(!$fileInfo){
            $this->_setResult(106, "上传文件为空");
            return FALSE;
        }
        foreach($fileInfo as $v){
            if(is_array($v['name'])){
                $this->_setResult(107, "不支持多文件上传");
                return FALSE;
            }
            $name = $v['name'];
            $tempName = $v['tmp_name'];
            $size = $v['size'];
            $this->_fileName = $name;
            $this->_filePath = $tempName;
            $this->_fileSize = $size;
        }
        if(!$this->_filePath){
            $this->_setResult(106, "上传文件为空");
            return FALSE;
        }
        //$this->_newFileName = $this->_makeNewFileName();
        $this->_newFileName = $name;
        //不存在信息就中断程序
        if(!$this->_filePath){
            exit();
        }
        return TRUE;
    }

    //获取结果
    private function _getResult()
    {
        return [
            "code"    => $this->_code,
            "result"  => $this->_data,
            "message" => $this->_msg[$this->_code]
        ];
    }

    //设置返回消息
    private function _setResult($code, $msg, $data = [])
    {
        $this->_code = $code;
        $this->_msg[$code] = $msg;
        $this->_data = $data;
    }

    //获取文件后缀
    private function _getFileHz()
    {
        if($this->_fileHz){
            return $this->_fileHz;
        }
        $fileName = strtolower(pathinfo($this->_fileName, PATHINFO_EXTENSION));
        $exp = explode(".", $fileName);
        $this->_fileHz = $exp[count($exp) - 1];
        return $this->_fileHz;
    }


    private function _makeUuid()
    {
        $chars = md5(uniqid(mt_rand(), TRUE));
        $uuid = substr($chars, 0, 8) . '-';
        $uuid .= substr($chars, 8, 4) . '-';
        $uuid .= substr($chars, 12, 4) . '-';
        $uuid .= substr($chars, 16, 4) . '-';
        $uuid .= substr($chars, 20, 12);
        return $uuid;
    }

    private function _makeNewFileName()
    {
        $this->_getFileHz();
        if($this->_option['prefix']){
            $name = sprintf("%s_%s_%s.%s", $this->_option['prefix'], date("Ymd_His", time()), md5($this->_makeUuid() . microtime(TRUE)), $this->_fileHz);
        } else{
            $name = sprintf("%s_%s.%s", date("Ymd_His", time()), md5($this->_makeUuid() . microtime(TRUE)), $this->_fileHz);
        }
        return $name;
    }


    //校验大小
    private function _checkSize()
    {
        if($this->_fileSize < $this->_option['limitSize']){
            return TRUE;
        }
        $msg = sprintf("上传超过限制,%sKB", $this->_option['limitSize'] / 1024);
        $this->_setResult(102, $msg);
        return FALSE;
    }

    //检测后缀名
    private function _checkHz()
    {
        if(in_array($this->_fileHz, $this->_option['limitHz'])){
            return TRUE;
        }
        $hz = implode(",", $this->_option['limitHz']);
        $msg = sprintf("只能上传%s的格式", $hz);
        $this->_setResult(101, $msg);
        return FALSE;
    }


    /**
     * 检查目录是否可写
     * @access protected
     * @param  string $path 目录
     * @return boolean
     */
    private function _checkPath()
    {
        $path = $this->_option['savePath'] . "/";
        if(is_dir($path)){
            return $path;
        }
        if(mkdir($path, 0755, TRUE)){
            return $path;
        }

        $this->_setResult(101, '创建目录失败', []);
        return FALSE;
    }


    /**
     * 普通文件上传
     * @return bool
     */
    private function _uploadFile()
    {
        $path = $this->_checkPath();
        if(!$path){
            return FALSE;
        }
        $this->_fileSaveName = $path . $this->_newFileName;
        $newFilePath = $this->_fileSaveName;
        if(is_file($newFilePath) && file_exists($newFilePath)){
            $this->_setResult(101, "文件已存在，请先删除");
            return FALSE;
        }
        if(move_uploaded_file($this->_filePath, $newFilePath)){
            $this->_setResult(200, "上传成功");
        } else{
            $this->_setResult(101, "上传失败");
        }
        return FALSE;
    }

    /**
     * 文件上传
     */
    public function upload()
    {
        //设置文件信息
        if(!$this->_fileInfoStatus){
            return $this->_getResult();
        }

        //校验大小
        if(!$this->_checkSize()){
            return $this->_getResult();
        }


        //校验后缀
        if(!$this->_checkHz()){
            return $this->_getResult();
        }

        $this->_uploadFile();

        return $this->_getResult();
    }

    //获取文件信息
    public function getFileInfo()
    {
        return $fileInfo = [
            "fileSaveName" => $this->_fileSaveName,
            "fileName"     => $this->_fileName,
            "newFileName"  => $this->_newFileName,
            "fileTmpName"  => $this->_filePath,//文件信息
            "fileSize"     => $this->_fileSize,
            "fileHz"       => $this->_fileHz
        ];
    }
}
$libVar = new libVar();
$key = $libVar->post("key", TRUE);
if($key == ""){
    $libVar->response("参数错误", [], 101);
}
//设置上传路径
if($key=="ryb"){
    $versionPrefix="4.0.0";
}else{
    $versionPrefix="3.0.0";
}
//设置上传路径
$savePath = dirname(dirname(__FILE__)) . "/update/$key/$versionPrefix/";
$option = [
    "savePath" => $savePath
];
$libObject = new libUploader($option);
$result = $libObject->upload();
$result['result']['key'] = $key;
//文件上传
echo json_encode($result, JSON_UNESCAPED_UNICODE);
exit();
